package sync_log

import (
	"go-kvsql/bytes_coder"
	"reflect"
	"strconv"
	"strings"
)

type LogType uint32

const (
	Set LogType = iota + 1
	Del
)

type SyncLog struct {
	LogId       uint64
	LogType     LogType
	Key         int64
	Value       interface{}
	LogKeyBytes []byte
	ValueBytes  []byte
}

func NewSyncLog(logId uint64, logType LogType, key int64, value interface{}) (*SyncLog, error) {
	syncLog := SyncLog{LogId: logId, LogType: logType, Key: key, Value: value}
	syncLog.LogKeyBytes = syncLog.encodeLogKey()
	var err error
	syncLog.ValueBytes, err = syncLog.encodeValue()
	if err != nil {
		return nil, err
	}
	return &syncLog, nil
}

func (this SyncLog) encodeLogKey() []byte {
	return []byte(strconv.FormatUint(this.LogId, 10) +
		"|" + strconv.Itoa(int(this.LogType)) +
		"|" + strconv.FormatInt(this.Key, 10))
}

func DecodeLogKey(logKey string) (logId uint64, logType LogType, key int64, err error) {
	stringArray := strings.Split(logKey, "|")
	logId, err = strconv.ParseUint(stringArray[0], 10, 64)
	if err != nil {
		return 0, 0, 0, err
	}
	theLogType, err := strconv.Atoi(stringArray[1])
	if err != nil {
		return 0, 0, 0, err
	}
	key, err = strconv.ParseInt(stringArray[2], 10, 64)
	if err != nil {
		return 0, 0, 0, err
	}
	return logId, LogType(theLogType), key, nil
}

func (this SyncLog) encodeValue() ([]byte, error) {
	return bytes_coder.EncodeJsonBytes(this.Value)
}

func DecodeValue(data []byte, valueType reflect.Type) (interface{}, error) {
	return bytes_coder.DecodeJsonBytes(data, reflect.New(valueType).Interface())
}
